#include "bg_editor.h"
#include "bg_decal.h"
#include "bg_partsys.h"
#include "bg_scene.h"
#include "bg_path.h"
#include "bg_waypoint.h"
#include "bg_biped.h"

#include "editor/editor_brush.h"
#include "editor/editor_selection.h"
#include "editor/editor_spriteset.h"

#include "application/game_script.h"
#include "bones/biped_instance.h"

#include "script/scripthelper.h"
#include "script/write_lua.h"
#include "graphics/graphics.h"
#include "graphics/graphics_util.h"

#include "math/spline2d.h"
#include "console/console.h"
#include "font/font_manager.h"
#include "dd/dd_man.h"
#include "ui/ui_manager.h"

#include "util/timer.h"				// log
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    

#include <cassert>
#include <algorithm>

#ifdef _ENABLE_LUABIND
#include <luabind/luabind.hpp>
#endif // _ENABLE_LUABIND

using namespace input;
using namespace background;
using namespace script;
using namespace editor;
static std::vector<std::string>		s_DecalSets;

///////////////////////////////////////////
// brushes
class SplineBrush : public EditorBrush
{
public:
	static EditorBrush*			Create(EditorMain* pMain) { return new SplineBrush(pMain); };

	SplineBrush(EditorMain* pEditor) :
		EditorBrush(pEditor),
			m_CurrentKnot(-1)
	{
	}
	SplineBrush(EditorMain* pEditor, const math::SplineCache2D& Spline) :
		EditorBrush(pEditor),
			m_CurrentKnot(-1)
	{
		for (int i=0; i<(int)Spline.GetNodeC(); i++)
		{
			m_Spline.InsertNode(Spline.GetNode(i)->Pos);
		}
	}
	virtual ~SplineBrush()
	{
		if (m_Spline.GetNodeC() > 1)
			((BGEditor*)m_pEditor)->GetScene()->AddPath(m_Spline, -1);
	}

	virtual void	Render(const math::Vec2& Offset, float Scale)
	{
		dd::Manager::Instance().AddSpline2(&m_Spline, 0.01f, 0xFFFFFFFF, true, Offset);
		math::Vec2	BoxSize(Scale*5.0f/(float)GraphicsUtil::WIDTH, Scale*5.0f/(float)GraphicsUtil::HEIGHT);
		math::Vec2	P = (GetPos() - Offset)*Scale;
		dd::Manager::Instance().AddBox2D(P-BoxSize, P+BoxSize, ColorRGBA(255, 0, 0, 255));
	}

	virtual void	SetPos(const math::Vec2& Pos) 
	{ 
		if (m_Spline.GetNodeC() <= 0)
		{
			m_Spline.InsertNode(GetPos());
		}
		if (m_CurrentKnot > 0)
		{
			m_Spline.SetNodePos(m_CurrentKnot, GetPos());
		} else
		{
			m_Spline.SetNodePos(m_Spline.GetNodeC()-1, GetPos());
		}

	}
	virtual bool	TryDelete(const math::Vec2& Pos) 
	{ 
		if (m_CurrentKnot >= 0)
		{
			m_Spline.DeleteNode(m_CurrentKnot);
			m_CurrentKnot = -1;
			return true;
		}
		int	NodeHit = -1;
		if (m_Spline.NodeHitTest(GetPos(), &NodeHit))
		{
			m_Spline.DeleteNode(NodeHit);
			m_CurrentKnot = -1;
			return true;
		}
		return false; 
	};		// see if we have any sub-components wants deleting

	virtual void	ReleaseLMB()
	{
		int	NodeHit = -1;
		if (m_CurrentKnot == -1 && m_Spline.NodeHitTest(GetPos(), &NodeHit))
		{
			// make sure it's not clicking on the last node in the set
			if (NodeHit != 0 && NodeHit != int(m_Spline.GetNodeC()) -1)
			{
				m_CurrentKnot = NodeHit;
				return;
			}
			// auto-close for closed loops?
		}
		if (m_CurrentKnot == -1)
		{
    		m_Spline.InsertNode(GetPos());
		}
		m_CurrentKnot = -1;
	}

	math::SplineCache2D		m_Spline;
	int						m_CurrentKnot;
	bool					m_AI;
};

class WayPointBrush : public EditorBrush
{
public:
	static EditorBrush*			Create(EditorMain* pMain) { return new WayPointBrush(pMain); };

	WayPointBrush(EditorMain* pEditor) :
		EditorBrush(pEditor)
	{
		assert(pEditor);
	}
	
	virtual ~WayPointBrush ()
	{
	}

	virtual void	Render(const math::Vec2& Offset, float Scale)
	{
		BGWaypoint::RenderDebugPos((GetPos() - Offset)*Scale);
//		((BGEditor*)m_pEditor)->GetScene()->SetSpawnPoint(m_Pos + ((BGEditor*)m_pEditor)->GetScene()->GetOffset());
	}
	virtual void	ReleaseLMB()
	{
		((BGEditor*)m_pEditor)->GetScene()->AddWaypoint(GetPos(), -1);
	}
	virtual bool	TryDelete(const math::Vec2& P) 
	{ 
		if (BGWaypoint* pPoint = ((BGEditor*)m_pEditor)->GetScene()->GetWaypoint(GetPos(), true))
		{
			delete pPoint;
			return true;
		}
		return true; 
	};		// see if we have any sub-components wants deleting

};

class PrefabSaveBrush : public EditorBrush
{
public:
	static EditorBrush*			Create(EditorMain* pMain) { return new PrefabSaveBrush(pMain); };

	PrefabSaveBrush(EditorMain* pEditor) :
		EditorBrush(pEditor),
		m_PlacedFirst(false)
	{
	}
	
	virtual ~PrefabSaveBrush ()
	{
	}

	virtual void	Render(const math::Vec2& Offset, float Scale)
	{
	// update positions continuously
		if (!m_PlacedFirst)
		{
			m_From = 	GetPos();
		} else
		{
			m_To = 		GetPos();
		}

	// render
		dd::Manager&	DD = dd::Manager::Instance();
		if (!m_PlacedFirst)
		{
			math::Vec2	BoxSize(12/800.0f, 12/600.0f);
			DD.AddBox2D((m_From-Offset-BoxSize)*Scale, (m_From+BoxSize-Offset)*Scale, ColorRGBA(255, 0, 255));
		} else
		{
			DD.AddBox2D((m_From-Offset)*Scale, (m_To-Offset)*Scale, ColorRGBA(255, 0, 255));
		}
	}
	virtual void	ReleaseLMB()
	{
		if (!m_PlacedFirst)
		{
			m_PlacedFirst = true;
		} else
		{
			// save the subwell
			std::string	File = GameScript::Instance()->GetSaveFileEx("lua", "Save Prefab File");
			if (File.size() > 3)
			{
				BGScene* pScene = ((BGEditor*)m_pEditor)->GetScene()->GetSubScene(m_From, m_To);
				if (pScene)
				{
					pScene->Save(File);
				}
				m_IsDone = true;
			}
		}
	}
	virtual bool	TryDelete(const math::Vec2& P) 
	{ 
		return true; 
	};		// see if we have any sub-components wants deleting

	math::Vec2	m_To, m_From;
	bool		m_PlacedFirst;

};




class DecalBrush : public ElementBrush
{
public:
	static EditorBrush*			Create(EditorMain* pMain) 
	{ 
		EditorBrush*	pBrush = new DecalBrush(pMain);
		UISpriteSet*	pSet   = pMain->CreateSpriteSelect(pBrush, "Decals");
		pSet->BuildSprite("decals/sprites2.lua", true);
//		pSet->BuildSprite("sprites/sprites.lua", false);
		//pSet->BuildSprite("img/sprites.lua", false);

		for (unsigned int i=0; i<s_DecalSets.size(); i++)
			pSet->BuildSprite(s_DecalSets[i], false);

		// setup the Selector
		return pBrush;  
	};


	DecalBrush(EditorMain* pEditor) :
		ElementBrush(pEditor),
		m_Type(BGDecal::DECAL_PLAIN),
		m_Additive(false)
		{
			SetElement(m_Name);
		}
	virtual void			UpdateSelection(const std::string& Name) 
	{
		SetElement(Name);
	};	// input from selection

	virtual bool	IsMoving() { return (m_Type != BGDecal::DECAL_PLAIN) && (m_Type != BGDecal::DECAL_GLOW); };
	virtual bool	ShowAnimation() { return m_Type != BGDecal::DECAL_PAN; };
	virtual void	SetElement(const std::string Name)
	{
		m_Name = Name;
		if (m_pElement)
		{
			((BGEditor*)m_pEditor)->GetScene()->DropElement(m_pElement);
	//		UTIL_SAFE_DELETE(m_pElement);
		}
		m_GetDirection = false;
		BGDecal* pDecal = NULL;
		switch (m_Type)
		{	
			case	BGDecal::DECAL_PLAIN: pDecal = new BGDecal(((BGEditor*)m_pEditor)->GetScene()); break;
			case	BGDecal::DECAL_PAN: pDecal = new BGPanDecal(((BGEditor*)m_pEditor)->GetScene()); break;
			case	BGDecal::DECAL_ROT: pDecal = new BGRotDecal(((BGEditor*)m_pEditor)->GetScene()); break;
			case	BGDecal::DECAL_BOB: pDecal = new BGBobDecal(((BGEditor*)m_pEditor)->GetScene()); break;
			case	BGDecal::DECAL_UV: pDecal = new BGUVDecal(((BGEditor*)m_pEditor)->GetScene()); break;
			case	BGDecal::DECAL_GLOW: pDecal = new BGGlowDecal(((BGEditor*)m_pEditor)->GetScene()); break;
		}
		if (pDecal)
		{
			pDecal->SetSprite(Name);
			pDecal->SetPos(GetPos());
			pDecal->SetDir(m_Dir);
			pDecal->SetRotation(m_Rotation);
			pDecal->SetSort(m_SortVal);

			AddElement(pDecal);

			std::string	DecalType;
			switch (m_Type)
			{	
				case	BGDecal::DECAL_PLAIN:	DecalType = "Plain"; break;
				case	BGDecal::DECAL_PAN:		DecalType = "transient"; break;
				case	BGDecal::DECAL_ROT:		DecalType = "Rotating"; break;
				case	BGDecal::DECAL_BOB:		DecalType = "Bobbing"; break;
				case	BGDecal::DECAL_UV:		DecalType = "UV"; break;
				case	BGDecal::DECAL_GLOW:	DecalType = "GLOW"; break;
			}

			std::string			Additive = "[SHIFT] Toggle Additive";
			if (m_Additive) 	Additive = "[SHIFT] Toggle Non-Additive";

			m_HelpText = "Decal Type [CTRL]: " +  DecalType + "\n" + Additive;
		}
		ElementBrush::SetElement(Name);

	}
	virtual void	AdjustClamp(float Dir)

	{
		EditorBrush::AdjustClamp(Dir);
		if (m_pElement)
		{
			BGDecal* pDecal = (BGDecal*)m_pElement;
			pDecal->SetAlpha(m_ClampedValue);
			pDecal->Tick(0);
		}
	}
	virtual void	Resize(const math::Vec2& Delta) 
	{
		if (m_pElement)
		{
			BGDecal* pElement = (BGDecal*)m_pElement;
			math::Vec2	S = pElement->GetSize();
			pElement->SetSize(pElement->GetSize() + (Delta * 2.0f));
		}
	};

	virtual void	ToggleA() 
	{
		if (m_pElement)
		{
			m_Type = (BGDecal::DECAL_TYPES)( (m_Type+1) % BGDecal::DECAL_C);
			math::Vec2	Size = m_pElement->GetSize();
			SetElement(m_Name);
			m_pElement->SetSize(Size);
		}
	};
	virtual void	ToggleB() 
	{
		m_Additive = !m_Additive;
		if (m_pElement)
		{
			BGDecal* pElement = (BGDecal*)m_pElement;
			pElement->SetAdditive(m_Additive);
		}
	};
protected:
	BGDecal::DECAL_TYPES		m_Type;
	bool						m_Additive;
};


class PartBrush : public ElementBrush
{
public:
	static EditorBrush*			Create(EditorMain* pMain) 
	{ 
		EditorBrush*	pBrush = new PartBrush(pMain);
		TextSelect*	pSet   = pMain->CreateTextSelect(pBrush, "Particles");
		pSet->FromDirectory("effects/*.p2d", false);
		// setup the Selector
		return pBrush;  
	};


	PartBrush(EditorMain* pEditor) :
		ElementBrush(pEditor)
		{
			SetElement(m_Name);
		}

	virtual void			UpdateSelection(const std::string& Name) 
	{
		m_Name = Name;
		SetElement(Name);
	};	// input from selection
	virtual void	Resize(const math::Vec2& Delta)
	{
		if (m_pElement)
		{
			m_pElement->SetSize(m_pElement->GetSize() + Delta);
		}
	}
	virtual void	SetElement(const std::string Name)
	{
		BGPartSys* pSys = new BGPartSys(((BGEditor*)m_pEditor)->GetScene());
		pSys->SetPartSys(Name);
		pSys->SetPos(GetPos());
		
		AddElement(pSys);
		ElementBrush::SetElement(Name);
	}
};

class BipedBrush : public ElementBrush
{
public:
	static EditorBrush*			Create(EditorMain* pMain) 
	{ 
		EditorBrush*	pBrush = new BipedBrush(pMain);
		TextSelect*	pSet   = pMain->CreateTextSelect(pBrush, "Bipeds");
		pSet->FromDirectory("bganim/*.sbp");
		// setup the Selector
		return pBrush;  
	};



	BipedBrush(EditorMain* pEditor) :
		ElementBrush(pEditor),
		m_pBiped(0)
		{
			SetElement(m_Name);
		}
	virtual void			UpdateSelection(const std::string& Name) 
	{
		m_Name = Name;
		SetElement(Name);
	}
	virtual void	ToggleA() 
	{
		if (m_pBiped && m_pBiped->GetBiped())
		{
			m_pBiped->GetBiped()->SetFlipped(!m_pBiped->GetBiped()->IsFlipped());
		}
	};
	virtual void	SetElement(const std::string Name)
	{
		m_pBiped = new BGBiped(((BGEditor*)m_pEditor)->GetScene());
		m_pBiped->SetAnimation(Name);
		m_pBiped->SetPos(GetPos());
		
		AddElement(m_pBiped);
		ElementBrush::SetElement(Name);

		m_HelpText = "[CTRL]: toggle Biped flipping";

	}
	BGBiped*	m_pBiped;
};


class BackgroundBrush : public EditorBrush
{
public:
	static EditorBrush*			Create(EditorMain* pMain) 
	{ 
		EditorBrush*	pBrush = new BackgroundBrush(pMain);
		UISpriteSet*	pSet   = pMain->CreateSpriteSelect(pBrush, "Backgrounds");
		pSet->BuildDir("backgrounds/*.jpg", true);
		pSet->BuildDir("backgrounds/*.png", false);
		pSet->BuildDir("ui_img/*.jpg", false);
		pSet->BuildDir("img/*.jpg", false);
		// setup the Selector
		return pBrush;  
	};


	BackgroundBrush(EditorMain* pEditor) :
		EditorBrush(pEditor),
		m_Rot(0),
		m_ReplaceAll(true)
		{
			SetElement(m_Name);
			ToggleA();
		}
	virtual void	SetElement(const std::string Name)
	{
		m_Name = Name;
		m_Sprite.Create(Name);
	}
	void			GetGrid(int& x, int& y)
	{
		math::Vec2	P = GetPos();
		x = (int)( P.x / ((BGEditor*)m_pEditor)->GetScene()->GetTileSize().x);
		y = (int)( P.y / ((BGEditor*)m_pEditor)->GetScene()->GetTileSize().y);
	}
	math::Vec2		TopLeft()
	{
		int x, y;
		GetGrid(x, y);
		return math::Vec2(	x * ((BGEditor*)m_pEditor)->GetScene()->GetTileSize().x, 
							y * ((BGEditor*)m_pEditor)->GetScene()->GetTileSize().y);
	}
	virtual void	Render(const math::Vec2& Offset, float Scale)
	{
		math::Vec2	P1 = (TopLeft() - GetOffset()) * Scale;
		m_Sprite.m_Pos = P1;
		m_Sprite.m_Size = m_Sprite.GetImageSize() * Scale;
		m_Sprite.Render();
		dd::Manager::Instance().AddBox2D(P1,
			P1 + m_Sprite.m_Size);
	}
	virtual bool	TryDelete(const math::Vec2& P) 
	{ 
		if (!((BGEditor*)m_pEditor)->GetScene()->HasTiles())
		{
			((BGEditor*)m_pEditor)->GetScene()->SetBackground("");
			return true;
		} else
		{
			int x, y;
			GetGrid(x, y);
			((BGEditor*)m_pEditor)->GetScene()->SetTile(x, y, "");
		}
		return false;
	}
	virtual void	ReleaseLMB()
	{
		if (!((BGEditor*)m_pEditor)->GetScene()->HasTiles())
		{
			((BGEditor*)m_pEditor)->GetScene()->SetBackground(m_Name);
			return;
		}
		if (m_ReplaceAll)
		{
			for (int x=0; x<((BGEditor*)m_pEditor)->GetScene()->GetWidth(); x++)
			for (int y=0; y<((BGEditor*)m_pEditor)->GetScene()->GetHeight(); y++)
			{
				((BGEditor*)m_pEditor)->GetScene()->SetTile(x, y, m_Name, m_Rot);
//				((BGEditor*)m_pEditor)->GetScene()->SetBackground(m_Name);
			}
		} else
		{
			int x, y;
			GetGrid(x, y);
			((BGEditor*)m_pEditor)->GetScene()->SetTile(x, y, m_Name, m_Rot);
//			((BGEditor*)m_pEditor)->GetScene()->SetBackground(m_Name);
		}
	}
	virtual void	Rotate(int Dir)
	{
		if (Dir < 0) m_Rot--; else m_Rot++;
		if (m_Rot > 3) m_Rot = 0; else
		if (m_Rot < 0) m_Rot = 3;

		m_Sprite.m_QuadRotation = (ui::UISprite::ROTATION)m_Rot;
	}
	virtual void	ToggleA() 
	{
		m_ReplaceAll = !m_ReplaceAll;
		if (m_ReplaceAll)
		{
			m_HelpText = "Toggle [CTRL] to replace single tile";
		} else
		{
			m_HelpText = "Toggle [CTRL] to replace all tiles";
		}
	};

	virtual void		UpdateSelection(const std::string& Name) 
	{
		BGScene*	pScene = (BGScene*)m_pEditor->GetGame();
		pScene->ClearTiles();
		pScene->SetBackground(Name);
		SetElement(Name);
	}

private:
	ui::UISprite		m_Sprite;
	int					m_Rot;
	bool				m_ReplaceAll;
};



BGEditor*	BGEditor::s_pBGEditor = NULL;

BGEditor::BGEditor(BGScene* pScene)  :
	EditorMain(pScene),
	m_pScene(pScene)
{
	s_pBGEditor = this;

	std::string strHelp = 
			"Editor Help [H]:						\n" 
			"(1) : Edit Decals						\n" 
			"(2) : Edit Background Tiles			\n" 
			"(3) : Edit Particles					\n" 
			"(4) : Edit BG animations				\n" 
			"(5) : 	Edit spline						\n" 

			"(W) : Edit Waypoint					\n" 

			"(U) : Toggle UI off					\n"
			"(H) : Toggle Help text off			\n"

			"(G) : Toggle Snap To Grid on/off		\n"
			"(D) : Toggle Debug Draw on/off		\n"

			"(F7) : Store prefab					\n"
			"(F8) : Load Background					\n"
			"(F9) : Save							\n"
			"(F10) : Load							\n";

	SetHelp(strHelp);
	// register the keys

	AddBrush("Spline", KEY_5, SplineBrush::Create);
	AddBrush("Waypoint", KEY_W,WayPointBrush::Create);
	AddBrush("Prefab", KEY_F7, PrefabSaveBrush::Create);
	AddBrush("Decal", KEY_1, DecalBrush::Create);
	AddBrush("Background", KEY_2, BackgroundBrush::Create);
	AddBrush("Part2D", KEY_3, PartBrush::Create);
	AddBrush("Biped", KEY_4, BipedBrush::Create);
}

BGEditor::~BGEditor()
{
	ui::UIManager::Instance().SetVisible(true);

	if (this == s_pBGEditor)
		s_pBGEditor = NULL;
}

void  BGEditor::  Init()
{
}

void  BGEditor::  Shutdown()
{
}

void	BGEditor:: RegisterDecalSet(const std::string& Decals)
{
	// check for duplicates
	for (unsigned int i=0; i<s_DecalSets.size(); i++)
	{
		if (strcmpi(s_DecalSets[i].c_str(), Decals.c_str())==0) return;
	}
	s_DecalSets.push_back(Decals);
}

bool  BGEditor::  CustomDelete(const math::Vec2& Pos)
{
	// try to delete a decal?
	math::Vec2	P = m_Offset  + ( Pos / m_Scale);
	if (m_pScene->DeleteElement(P))
	{
		return true;
	}

	// look for splines to delete
	if (m_pScene->GetPath(P))
	{
		return true;
	}

	if (BGWaypoint* pPoint = m_pScene->GetWaypoint(P, true))
	{
		delete pPoint;
		return true;
	}
	if (BGPath* pPath = m_pScene->GetPath(P))
	{
		m_pScene->DeletePath(P);
		return true;
	}

	return false;

}

//////////////
// BG Element brush
ElementBrush::ElementBrush(EditorMain* pEditor) :
		EditorBrush(pEditor),
		m_pElement(NULL),
		m_Rotation(0),
		m_SortVal(1),
		m_GetDirection(false)
{
}

ElementBrush::~ElementBrush ()
{
	if (m_pElement)		
	{
		((BGEditor*)m_pEditor)->GetScene()->DropElement(m_pElement);
		delete m_pElement;
	}
}

void	ElementBrush::Tick(float dt)
{
	if (m_pElement)
	{
	}
}
bool	ElementBrush::TryDelete(const math::Vec2& Pos) 
{ 
	bool	Deleted = false;
	if (m_pElement)
	{

		m_pElement->SetActive(false);
		if (((BGEditor*)m_pEditor)->GetScene()->DeleteElement(GetPos()))
		{
			Deleted = true;
		}
		m_GetDirection = false;
		m_pElement->SetActive(true);
	}
	return Deleted;
};	// else we'll accidentally delete the one we're on
void	ElementBrush::SetPos(const math::Vec2& Pos) 
{ 
	math::Vec2	P = GetPos();
	if (m_pElement)
	{
		if (!m_GetDirection)
		{
			if (m_pEditor->ShouldSnapToGrid())
			{
				m_pElement->SetPos(P);
			} else
			{
				m_pElement->SetPos(P - (m_pElement->GetSize()*0.5f));
			}

		} else
		if (ShowAnimation())
		{
			m_pElement->SetDir(m_Dir);
		}
		
		UpdateElement();
	}
	m_LastPos = Pos;
}

void	ElementBrush::UpdateElement()
{
	// force an update and re-sort
	if (m_pElement)
	{
		((BGEditor*)m_pEditor)->GetScene()->DropElement(m_pElement);
		((BGEditor*)m_pEditor)->GetScene()->AddElement(m_pElement);
	}
}
void	ElementBrush::SetElement(const std::string Name)
{
	SetPos(m_LastPos);
};
void	ElementBrush::AddElement(BGElement* pEl)
{
	if (m_pElement)
	{
		((BGEditor*)m_pEditor)->GetScene()->DropElement(m_pElement);
		UTIL_SAFE_DELETE(m_pElement);
	}
	m_pElement = pEl;
	((BGEditor*)m_pEditor)->GetScene()->AddElement(m_pElement);

}
void	ElementBrush::Render(const math::Vec2& Offset, float Scale)
{
	float	LineS = 0.025f;
	float	StartY = 0.65f;
	if (m_pEditor->ShowHelp())
	{
		FontManager::Instance().Print(math::Vec2(0.02f, StartY+=LineS), "Layer : %.1f. [Up/Down for single steps, PgUp/PgDown for steps of 10]. >0 is above the game board, ", m_SortVal);
		FontManager::Instance().Print(math::Vec2(0.02f, StartY+=LineS), "Rotation : %.1f. [Left/Right to rotation 90 degrees. Mousewheel to rotate single degrees", m_Rotation);
		FontManager::Instance().Print(math::Vec2(0.02f, StartY+=LineS), "Alpha : %.3f. [Ins/Del]", m_ClampedValue);
	}
	if (m_GetDirection && m_pElement)
	{
		math::Vec2	From = m_OrigPos;
		math::Vec2	To = m_pEditor->GetMousePos();
		dd::Manager::Instance().AddLine2D(From, To, 0xFFFFFFFF, true);
		m_Dir = To-From;
		if (ShowAnimation())
			m_pElement->SetDir(m_Dir);
		
		if (m_pEditor->ShowHelp())	
		{
			FontManager::Instance().Print(math::Vec2(0.04f, StartY+=LineS), "[Enter] to turn off motion");
		}
	}
	if (m_pElement)
	{
		if (!m_GetDirection)
			m_pElement->SetPos(GetPos());
	}
	if (m_pElement && m_pEditor->ShowDebug())
	{
		m_pElement->RenderDebug(Offset, Scale);
	}
}
void	ElementBrush::OnEnter()
{
	ReleaseLMB();
}
void	ElementBrush::ReleaseLMB()
{
	if (!m_pElement) return;
	if (m_GetDirection )
	{
		m_pElement->SetDir(m_Dir);
		m_pElement->SetPos(GetOffset() + (m_OrigPos / GetScale()));
		m_Dir = math::Vec2(0,0);

		// create a new one
		m_pElement = NULL;	// stop it from deleting us
		SetElement(m_Name);

		m_GetDirection = false;
	} else
	{
		m_OrigPos = m_pEditor->GetMousePos();
		m_GetDirection = true;
		if (!IsMoving())
			ReleaseLMB();// place immadiately
	}


}

void	ElementBrush::Rotate(int Dir)
{
	m_Rotation += Dir;
	if (m_Rotation > 360)	m_Rotation -= 360;
	if (m_Rotation < 0)		m_Rotation += 360;
	if (m_pElement)		
		m_pElement->SetRotation(m_Rotation);
}

void	ElementBrush::RotateGrid(int Dir)
{
	m_Rotation += Dir;
	if (m_Rotation > 360)	m_Rotation -= 360;
	if (m_Rotation < 0)		m_Rotation += 360;

	if (m_Rotation > 260)	m_Rotation = 270;	else
	if (m_Rotation > 170)	m_Rotation = 180;	else
	if (m_Rotation > 80)	m_Rotation = 90;	else
							m_Rotation = 0;	

	if (m_pElement)		
		m_pElement->SetRotation(m_Rotation);
}

void	ElementBrush::Raise(int Dir) 
{ 
	m_SortVal += Dir;
	if (m_pElement)
	{
		m_pElement->SetSort(m_SortVal);
		UpdateElement();
	}
}

	BGPath*			GetSpline(const math::Vec2& P);
